/*
 * Copyright 2008 Carnegie Mellon University
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *  
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, 
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package edu.cmu.lti.sepia.task.retrieval;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

import edu.cmu.lti.sepia.data.db.SQL;
import edu.cmu.lti.sepia.data.db.TaskDAO;
import edu.cmu.lti.sepia.data.resource.ResourceManager;
import edu.cmu.lti.sepia.infra.topic.model.Task;
import edu.cmu.lti.sepia.task.retrieval.indri.IndriUtil;
import edu.cmu.lti.sepia.task.retrieval.indri.ParsedDocument;
import edu.cmu.lti.sepia.task.retrieval.indri.QueryEnvironment;
import edu.cmu.lti.sepia.task.retrieval.indri.ScoredExtentResult;

public class Retriever {
	//Key: taskNameShort
  private static Map<String, Retriever> retrievers = new HashMap<String, Retriever>();
  public String validationReport;
  private QueryEnvironment env;
    
  public static Retriever getInstance(String taskNameShort) throws Exception {
    Retriever r = retrievers.get(taskNameShort);
    SQL sql = new SQL();
//    if (r == null) {
//      Task task = TaskDAO.findByTaskNameShort(sql, taskNameShort);
//      r = new Retriever(task.getTrgLang(), task.getIndices());
//      retrievers.put(taskNameShort, r);
//    } else {
//      r.env.updateIndriHome( ResourceManager.indriHome );
//    }
    Task task = TaskDAO.findByTaskNameShort(sql, taskNameShort);
    r = new Retriever(task.getTrgLang(), task.getIndices());
    retrievers.put(taskNameShort, r);
    sql.close();
    return r;
  }
    
  private Retriever(String lang, String indices) throws Exception {
    env = new QueryEnvironment( ResourceManager.indriHome );
    String[] indexArray = indices.split(";");
    validationReport = env.validateIndri(ResourceManager.indriHome, indexArray);
    for (String index : indexArray) {
      File f = new File(index);
      if (!f.exists()) {
        System.err.println("ERROR: Index cannot be found at: " + f.getAbsolutePath());
        continue;
      }
      env.addIndex(index);
    }
  }

  public ParsedDocument[] retrieve(String query, int maxDocs) {
    try {
      ScoredExtentResult[] sers = env.runQuery(query, maxDocs);
      ParsedDocument[] pds = env.documents(sers);
      return pds;
    } catch (Exception e) {
      // StringWriter sw = new StringWriter();
      // PrintWriter pw = new PrintWriter(sw);
      // e.printStackTrace( pw );
      // return "No results matched."+sw.toString();
      return null;
    }
  }

  public String getDocument(String lang, ParsedDocument pd) {
    return DocumentFormatter.getCleanDocument(lang, pd.content);
  }

  public String getSnippet(String document, String[] queryTerms) {
    String snippet = DocumentFormatter.getSnippet(document, queryTerms);
    snippet = Highlighter.highlightWithQuery(snippet, queryTerms);
    return snippet;
  }

  // used by a jsp
  public static String getHighlightedDoc(String document, String[] queryTerms) {
    // order matters. Don't replace <Strong> after highlighting
    document = DocumentFormatter.cleanUp(document);
    String content = Highlighter.highlightWithQuery(document, queryTerms);
    // unclean up br tags
    // content = content.replaceAll("&lt;br[ ]?/?&gt;", "<br>\n"); // keep them as is
    // content = content.replaceAll("<([/]?(?:TEXT|DOCNO|DOC|HEADLINE|DATE))>", "&lt;$1&gt;");
    return content;
  }

  public String getDocumentFromExternalId(String externalId) {
    String content = null;
    try {
      content = env.getDocumentFromDocno("docno", externalId);
    } catch (Exception e) {
      e.printStackTrace();
    }
    return (content != null && content.length() > 0) ? DocumentFormatter.cleanUp(content) : null;
  }

  public String dumpInfo() {
    return env.dumpInfo();
  }
  
  public static void main(String[] args) throws Exception {
    String text = "Hello world.";
    String[] queryTerms = { "world" };
    System.out.println(Highlighter.highlightWithQuery(text, queryTerms));

    String text2 = "protein protein-protein interaction.";
    String query = "#combine ( #1( protein.p ) )";
    String[] queryTerms2 = IndriUtil.getQueryTerms(query);
    System.out.println(Highlighter.highlightWithQuery(text2, queryTerms2));

    Retriever r = new Retriever("ja", "/home/javelin/indri_indices/kiji/wikipedia.plain.index");
    String result = r.retrieve("1", 10)[0].content;
    System.out.println("Retrieved: " + result);
  }

}
